﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using Microsoft.Http;
using System.Configuration;
using System.Reflection;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Data.SqlClient;

namespace KeanuMvc.Reference {

    public class ClientRestService : IDisposable {

        #region Fields
        private HttpWebRequest httpWebRequest = null;
        private HttpWebResponse response = null;
        private Dictionary<string, string> headerOptional = null;
        #endregion

        #region Constructors
        /// <summary>
        /// Helper Rest
        /// </summary>
        public ClientRestService() {
            headerOptional = new Dictionary<string, string>();
        }
        #endregion

        public Dictionary<string, string> HeaderOptional {
            get {
                return headerOptional;
            }
        }

        public HttpWebResponse ObjectResponse {
            get {
                return response;
            }
        }

        #region Methods

        #region Json
        /// <summary>
        /// Post data json
        /// </summary>
        /// <param name="Address">Address url</param>
        /// <param name="DataToPost">Json data</param>
        /// <returns>Return value</returns>
        public StringReader PostJson(string Address, string DataToPost) {
            return PostPutDelete(Address, DataToPost, "POST", true);
        }

        /// <summary>
        /// Put data json
        /// </summary>
        /// <param name="Address">Address url</param>
        /// <param name="DataToPost">Json data</param>
        /// <returns>Return value</returns>
        public StringReader PutJson(string Address, string DataToPost) {
            return PostPutDelete(Address, DataToPost, "PUT", true);
        }

        /// <summary>
        /// Delete data json
        /// </summary>
        /// <param name="Address">Address url</param>
        /// <param name="DataToPost">Json data</param>
        /// <returns>Return value</returns>
        public StringReader DeleteJson(string Address, string DataToPost) {
            return PostPutDelete(Address, DataToPost, "DELETE", true);
        }

        /// <summary>
        /// Get data json
        /// </summary>
        /// <param name="Address">Address url</param>
        /// <param name="DataToPost">Json data</param>
        /// <returns>Return value</returns>
        public StringReader GetJson(string Address) {
            StringReader returnValue = null;
            try {
                SetHeader(Address, "GET", true);
                GetReponse(out returnValue, Address);
            } catch {
            } finally {
            }
            
            return returnValue;
        }

        #endregion

        #region Xml

        public StringReader PostXml(string Address, string DataToPost) {
            return PostPutDelete(Address, DataToPost, "POST", false);
        }

        public StringReader PutXml(string Address, string DataToPost) {
            return PostPutDelete(Address, DataToPost, "PUT", false);
        }

        public StringReader DeleteXml(string Address, string DataToPost) {
            return PostPutDelete(Address, DataToPost, "DELETE", false);
        }

        public StringReader GetXml(string Address) {
            StringReader returnValue = null;
            SetHeader(Address, "GET", false);
            GetReponse(out returnValue, Address);
            return returnValue;
        }
        #endregion

        private StringReader PostPutDelete(string Address, string DataToPost, string Method, bool IsJson) {
            StringReader returnValue = null;
            try {
                ProcessPost(Address, DataToPost, Method, IsJson);
                GetReponse(out returnValue, Address);
            } catch (Exception ex) {
                throw ex;
            }
            
            return returnValue;
        }

        private void ProcessPost(string Address, string DataToPost, string Method, bool IsJson) {
            SetHeader(Address, Method, IsJson);
            httpWebRequest.KeepAlive = true;

            using (Stream requestStream = httpWebRequest.GetRequestStream()) {
                var bytes = Encoding.UTF8.GetBytes(DataToPost);
                requestStream.Write(bytes, 0, bytes.Length);
                requestStream.Close();
            }


        }

        private void GetReponse(out StringReader readerValue, string Address) {
            try {
                response = httpWebRequest.GetResponse() as HttpWebResponse;
                using (StreamReader responseReader = new StreamReader(response.GetResponseStream())) {
                    readerValue = new StringReader(responseReader.ReadToEnd());
                    responseReader.Close();
                }
            } catch (Exception ex) {
                readerValue = null;
                throw ex;
            }
            
        }

        private void SetHeader(string Address, string Method, bool IsJson) {
            httpWebRequest = WebRequest.Create(Address) as HttpWebRequest;
            httpWebRequest.ContentType = IsJson ? "application/json" : "application/xml";
            httpWebRequest.Method = Method;

            foreach (var item in headerOptional) {
                httpWebRequest.Headers.Add(item.Key, item.Value);
            }
        }

        public void Dispose() {
            if (httpWebRequest != null) httpWebRequest = null;
        }

        #endregion
    }
}